package com.lagou.config.config_center;

import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.pool.DruidPooledConnection;
import com.alibaba.fastjson.JSON;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.I0Itec.zkclient.IZkDataListener;
import org.I0Itec.zkclient.ZkClient;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.domain.EntityScan;

import java.sql.SQLException;

@SpringBootApplication
@EntityScan(basePackages = "com.lagou.config.config_center")
public class ConfigCenterApplication {

	private static ZkClient zkClient;
	private static JDBCConf initJdbcConf = new JDBCConf(
			"jdbc:mysql://linux123:3306/zkweb?useUnicode=true&characterEncoding=utf8",
			"root", "yue20096016");
	private static DruidDataSource ds;

	public static void main(String[] args) throws JsonProcessingException, SQLException {
		SpringApplication.run(ConfigCenterApplication.class, args);
		initZk();
		configDruidSource();
	}

	/**
	 * 初始化ZK
	 */
	public static void initZk(){
		zkClient = new ZkClient("linux121:2181,linux122:2181,linux123:2181");
		//指定序列化类型
		zkClient.setZkSerializer(new ZkStrSerializer());

		//创建/mysql节点，并赋初值
		if (!zkClient.exists("/mysql")){
			String s = JSON.toJSONString(initJdbcConf);
			System.out.println(s);
			zkClient.createPersistent("/mysql",s);
		}

		//监控/mysql节点数据变化，数据变化后创建新的连接池
		zkClient.subscribeDataChanges("/mysql", new IZkDataListener() {
			@Override
			public void handleDataChange(String path, Object data) throws Exception {
				System.out.println(path + " data is changed, new data " + data);
				ds.close();
				configDruidSource();
			}

			//节点删除后，关闭连接池
			@Override
			public void handleDataDeleted(String path) throws Exception {
				System.out.println(path + " is delete!");
				ds.close();
			}
		});
	}

	/**
	 * 配置数据库连接池
	 * @throws JsonProcessingException
	 * @throws SQLException
	 */
	public static void configDruidSource() throws JsonProcessingException, SQLException {
		JDBCConf jconf = getJdbcConfig();
		updateDruidSource(jconf);
	}

	/**
	 * 根据配置信息创建新的连接池
	 */
	public static void updateDruidSource(JDBCConf jdbcConf) throws SQLException {

		ds = new DruidDataSource();
		ds.setDriverClassName("com.mysql.jdbc.Driver");
		ds.setUrl(jdbcConf.getUrl());
		ds.setUsername(jdbcConf.getUsername());
		ds.setPassword(jdbcConf.getPassword());

		//设置连接数等参数
		ds.setInitialSize(5);
		ds.setMaxActive(10);
		ds.setMaxWait(1000);
		DruidPooledConnection conn = ds.getConnection();
		System.out.println("新的连接池创建成功-->" + conn.getClientInfo());
	}

	/**
	 * 从zookeeper中获取连接池配置信息
	 */
	public static JDBCConf getJdbcConfig() throws JsonProcessingException {
		Object data = zkClient.readData("/mysql");
		JDBCConf jdbcConf = JSON.parseObject(data.toString(), JDBCConf.class);
		System.out.println(jdbcConf.toString());
		return jdbcConf;
	}
}
